// **************************************************************
// *															*
// *	P A R S E R			(Header)							*
// *															*
// *	CLASSES:	Parser										*
// *															*
// **************************************************************

#ifndef	parser_h
#define	parser_h

#include "token.h"
#include "scanner.h"
#include "symtab.h"
#include "code.h"

class Parser {

private:
	Scanner* m_lexan;		// Lexical analyzer
	SymbolTable* m_symTab;	// Symbol table
	Token* m_currentToken;	// Current token
	Code*  m_code;			// Code
	bool m_parserError;		// Has a parsing error occurred?
	int  m_totalErrors;		// Total number of errors

	bool tokenCodeIn(TokenCode tc, const TokenCode *plist);	// Is the given tokencode in the list
	void recover(const TokenCode *plist);	// keep asking for tokens until token is found in the list
	void getToken();						// ask lexical analyzer for next token
	TokenCode getTokenCode();
	void out(char const *out);				// debugging output
	void match(TokenCode tc);				// Walk over tokencode tc.  If not a match; report an error
	void setError(char *err);				// sets an appropriate error message
	void expectedTokenCode(TokenCode tc);


//	SymbolTableEntry* parseProgramDefinition();   this is from the given code in codegen part... we cant use it here


	// deprecated functions in our grammar, appears in the parser template in CodeGen project
	//void parseIdOrProcedureStatement(SymbolTableEntry* prevEntry);
	//void parseArrayReference();

	void parseArguments();
	void parseCompoundStatement();

	// new function from parser template in CodeGen project
	//void parseDeclarations(bool subProgramHead);

	void parseDeclarations();
	void parseDeclarationsLRE();

	// new function from parser template in CodeGen project
	//SymbolTableEntry* parseExpression();

	SymbolTableEntry* parseExpression(SymbolTableEntry *prevEntry);
	SymbolTableEntry* parseExpressionLF(SymbolTableEntry *prevEntry);

	// new functions from parser template in CodeGen project
	//void parseExpressionList(SymbolTableEntry* prevEntry);
	//void parseExpressionListMore(EntryList* eList);

	void parseExpressionList();
	void parseExpressionListLRE();
	SymbolTableEntry* parseFactor(SymbolTableEntry *prevEntry);
	SymbolTableEntry* parseFactorLF();

	// new functions from parser template in CodeGen project
	//void parseIdentifierList(EntryList *eList);
	//void parseIdentifierListMore(EntryList *eList);
	//void parseIdentifierListAndType(bool subProgramHead);


	void parseIdentifierList(bool programHead, bool subprogramHead);
	void parseIdentifierListLRE(bool programHead, bool subprogramHead);
	void parseOptionalStatements();
	void parseParameterList();
	void parseParameterListLRE();
	void parseProgram();
	SymbolTableEntry* parseSign();
	
	// new functions from parser template in CodeGen project
	//SymbolTableEntry* parseSimpleExpression();
	//SymbolTableEntry* parseSimpleExpressionRelop(SymbolTableEntry* prevEntry);
	//SymbolTableEntry* parseSimpleExpressionAddop(SymbolTableEntry* prevEntry);
	
	SymbolTableEntry* parseSimpleExpression(SymbolTableEntry *prevEntry);
	SymbolTableEntry* parseSimpleExpressionLRE(SymbolTableEntry *prevEntry);
	void parseStandardType();
	void parseStatement();
	void parseStatementLF(SymbolTableEntry* prevEntry);
	void parseStatementList();
	void parseStatementListLRE();
	void parseSubprogramDeclaration();
	void parseSubprogramDeclarations();
	void parseSubprogramDeclarationsLRE();
	void parseSubprogramHead();
	
	// new functions from parser template in CodeGen project
	//SymbolTableEntry* parseTerm();
	//SymbolTableEntry* parseTermRest(SymbolTableEntry* prevEntry);
	
	SymbolTableEntry* parseTerm(SymbolTableEntry *prevEntry);
	SymbolTableEntry* parseTermLRE(SymbolTableEntry *prevEntry);
	void parseType();
	SymbolTableEntry* parseVariable();
	SymbolTableEntry* parseVariableLF();




	/* Code generation */
	SymbolTableEntry* newLabel();
	void createLabel(SymbolTableEntry* entry);
	SymbolTableEntry* newTemp();
	CodeOp opToCode(OpType op);

public:
	Parser();
	Parser(bool listing);
	~Parser();
	void parse();
	SymbolTable* getSymbolTable();
	Code* getCode();
	int totalErrors();

};



#endif
